# coding: utf-8
# @Author: cyl
# @File: assert_handle.py
# @Time: 2022/07/25 21:06:10
import sys
from collections import Counter


class Assertion:
    """公共断言类"""

    @classmethod
    def assertEqualValue(cls, reality_value, expected_value):
        """
        校验等于预期值
        :param reality_value: 实际值
        :param expected_value: 预期值
        """
        assert expected_value == reality_value, "实际值: {} != 预期值: {}".format(reality_value, expected_value)

    @classmethod
    def assertNotEqualValue(cls, reality_value, expected_value):
        """
        校验不等于预期值
        """
        assert expected_value != reality_value, f"实际值等于预期值,实际值为:{reality_value}, 预期值为:{expected_value}"

    @classmethod
    def assertTwoCodes(cls, response, code=1, msg="", _type="code", is_other=False):
        """
        先校验状态码再校验code
        :param response:  响应体
        :param code: 状态码
        :param msg: 返回信息
        :param _type: 校验类型 code -> 校验状态码; msg -> 校验返回信息
        :param is_other: 是否校验除了响应码之外的信息
        """
        cls.assertEqualValue(response.status_code, 200)
        if is_other:
            ResponseJson = response.json()
            match _type:
                case "code":
                    cls.assertEqualValue(ResponseJson.get("code", None), code)
                case "msg":
                    cls.assertEqualValue(ResponseJson.get("msg", None), msg)
                case "all":
                    cls.assertEqualValue(ResponseJson.get("code", None), code)
                    cls.assertEqualValue(ResponseJson.get("msg", None), code)

    @classmethod
    def assertStartswith(cls, data, expected_value):
        """
        校验以预期值开头
        :param data: 校验的data数据
        :param expected_value: 预期值
        :return:
        """
        if isinstance(data, str):
            assert data.startswith(expected_value), "没有以预期值: {} 开头".format(expected_value)
        else:
            assert False, '只支持 str 的校验, 其余暂不支持'

    @classmethod
    def assertEndswith(cls, data, expected_value):
        """
        校验以预期值结尾
        :param data: 校验的data
        :param expected_value: 预期值
        :return:
        """
        if isinstance(data, str):
            assert data.endswith(expected_value), "没有以预期值: {} 结尾".format(expected_value)
        else:
            assert False, '只支持 str 的校验, 其余暂不支持'
    
    @classmethod
    def assertIsNone(cls, reality_value):
        """
        校验是否等于None
        :param reality_value: 实际值
        :return:
        """
        if reality_value is None:
            assert True
        else:
            assert False, "校验值不等于None"

    @classmethod
    def assertIsEmpty(cls, reality_value):
        """
        校验值为空, 当传入值为None、False、空字符串""、0、空列表[]、空字典{}、空元组()都会判定为空
        :param reality_value: 实际值
        :return:
        """
        if not reality_value:
            assert True
        else:
            assert False, "校验值不为空, 值为: {}".format(reality_value)

    @classmethod
    def assertIsNotEmpty(cls, reality_value):
        """
        校验值不为空, 当传入值为None、False、空字符串""、0、空列表[]、空字典{}、空元组()都会判定为空
        :param reality_value: 实际值
        :return:
        """
        if reality_value:
            assert True
        else:
            assert False, f"校验值为空,值为:{reality_value}"

    @classmethod
    def assertListRepetition(cls, lists: list):
        """
        校验列表中是否有重复项
        """
        if isinstance(lists, list):
            repetition = {key: value for key, value in dict(Counter(lists)).items() if value > 1}
            if repetition:
                assert False, '列表中有重复项, 重复项为: {}'.format(repetition)
        else:
            assert False, '传入的数据不是一个list'

    @classmethod
    def assertNotContains(cls, original_value, contains_value):
        """
        断言字符串中不包含指定字符串
        :param original_value: 实际字符串
        :param contains_value: 预期字符串
        """
        if isinstance(original_value, str) and isinstance(contains_value, str):
            assert contains_value not in original_value, f"实际数据包含了 {contains_value}, 实际值为:{original_value}"
        else:
            assert False, "只支持str类型"
